;/******************************************************************
;* Copyright ARM Limited 2004.  All rights reserved.
;*	
;*
;* sysutil_a.s
;*	Assembler graphic routines
;*
;* Target:	ARM26EJ-S
;******************************************************************/
 
;-------------------------------------------------------------------
;	Module	: sysutil_a.s
;	Scope	: Graphical manipulation routines
;-------------------------------------------------------------------

;-------------------------------------------------------------------
; Include Files:
;-------------------------------------------------------------------

	;INCLUDE	sysutil_h.s

;-------------------------------------------------------------------
; Constant Declarations:
;-------------------------------------------------------------------

;-------------------------------------------------------------------
; Macro Declarations:
;-------------------------------------------------------------------

;-------------------------------------------------------------------
; Structure Declarations:
;-------------------------------------------------------------------

;-------------------------------------------------------------------
; Local Variables Declarations:
;-------------------------------------------------------------------

;-------------------------------------------------------------------
; Local Function Prototypes:
;-------------------------------------------------------------------

;-------------------------------------------------------------------
; Global Variable Declarations:
;-------------------------------------------------------------------

;-------------------------------------------------------------------
; Global Function Prototypes:
;-------------------------------------------------------------------

;-------------------------------------------------------------------

	AREA GraphicFn, CODE, READONLY
	CODE32
	ALIGN	4

;-------------------------------------------------------------------
;
;	Function: drvsys_clear_buf 
;   
;   void drvsys_clear_buf(unsigned long*, long, unsigned long)
;
;	Purpose : Set entire buffer to a known value.
;
;	Assumptions : Buffer is on a suitable 8, 4, or 2 word boundary
;
;	Parameters : 
;	  r0	*unsigned long		Buffer pointer.
;	  r1	long				Size in bytes
;	  r2	unsigned long		Fill value 
;	Returns :
;	  	
;
;-------------------------------------------------------------------

	GLOBAL	fgl_fast_transfer_port

fgl_fast_transfer_port

	STMFD	sp!, {r4-r10}			; Save work registers
	
	;// Branch to routine from buffer width
	
	ANDS	r10,r1,#&1F				; multiple of 32 bytes?
	BEQ		cb_32_start
	ANDS	r10,r1,#&F				; multiple of 16 bytes?
	BEQ		cb_16_start
	
	;// Else must be multiple of 8 bytes so do this routine
	
cb_08_start
	MOV     r1,r1,lsr #3			; Adjust buf size to no. transfers.
	MOV		r3,r2					; Fill another reg with value

cb_08_loop
	STMIA	r0!,{r2-r3}				; write to buffer (1 write = 2 words)
	
	SUBS	r1,r1,#1				; dec buffer size counter
    BNE		cb_08_loop				; loop until count is negative
    B		cb_end
    
	;// Multiple of 32 so do this routine
	
cb_32_start
	MOV     r1,r1,lsr #5			; Adjust buffer size to no. transfers.
	MOV		r3,r2					; Fill up more registers 
	MOV		r4,r2					; with the fill value
	MOV		r5,r2						
	MOV		r6,r2						
	MOV		r7,r2						
	MOV		r8,r2						
	MOV		r9,r2						

cb_32_loop
	STMIA	r0!,{r2-r9}				; write to buffer (1 write = 8 words)
	
	SUBS	r1,r1,#1				; dec buffer size counter
    BNE		cb_32_loop				; loop until count is negative
    B		cb_end

	;// Multiple of 16 so do this routine
	
cb_16_start
	MOV     r1,r1,lsr #4			; Adjust buffer size to no. transfers.
	MOV		r3,r2					; Fill up more registers 
	MOV		r4,r2					; with the fill value
	MOV		r5,r2						

cb_16_loop
	STMIA	r0!,{r2-r5}				; write to buffer (1 write = 4 words)
	
	SUBS	r1,r1,#1				; dec buffer size counter
    BNE		cb_16_loop				; loop until count is negative

	;// End this routine
	
cb_end    
	LDMFD	sp!,{r4-r10}			; Restore the work registers.
	MOV		pc,lr					; Return

	;.size	drvsys_clear_buf,.setbuf_End-drvsys_clear_buf;

	END



;#if 0
;
;        AREA Block, CODE, READONLY      ; name this block of code
;
;num     EQU     20              ; Set number of words to be copied
;
;        ENTRY                   ; mark the first instruction to call
;
;start
;        LDR     r0, =src        ; r0 = pointer to source block
;        LDR     r1, =dst        ; r1 = pointer to destination block
;        MOV     r2, #num        ; r2 = number of words to copy
;
;        MOV     sp, #0x400      ; set up stack pointer (r13)
;blockcopy       
;        MOVS    r3,r2, LSR #3   ; number of eight word multiples
;        BEQ     copywords       ; less than eight words to move ?
;
;        STMFD   sp!, {r4-r11}   ; save some working registers
;octcopy
;        LDMIA   r0!, {r4-r11}   ; load 8 words from the source
;        STMIA   r1!, {r4-r11}   ; and put them at the destination
;        SUBS    r3, r3, #1              ; decrement the counter
;        BNE     octcopy         ; ... copy more
;
;        LDMFD   sp!, {r4-r11}   ; don't need these now - restore originals
;
;copywords
;        ANDS    r2, r2, #7      ; number of odd words to copy
;        BEQ     stop            ; No words left to copy ?
;wordcopy
;        LDR     r3, [r0], #4    ; a word from the source
;        STR     r3, [r1], #4    ; store a word to the destination
;        SUBS    r2, r2, #1      ; decrement the counter
;        BNE     wordcopy        ; ... copy more
;
;stop
;        MOV     r0, #0x18       ; angel_SWIreason_ReportException
;        LDR     r1, =0x20026    ; ADP_Stopped_ApplicationExit
;        SVC     #0x123456       ; ARM semihosting (formerly SWI)
;
;
;        AREA BlockData, DATA, READWRITE
;
;src     DCD     1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4
;dst     DCD     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
;
;        END
;
;#endif